package list

import (
	"errors"
	"fmt"
)

const MAXSIZE = 10

type Node interface{}

type SqList struct {
	data   [MAXSIZE]Node
	length int
}

/**
 * 初始化顺序线性表
 */
func InitList() *SqList {
	return &SqList{}
}

/**
 * 返回L中数据元素个数
 */
func (list *SqList) ListLength() int {
	return list.length
}

/**
 * 往顺序线性表中插入一个元素,注意pos是指位置，第1个位置的数组是从0开始
 */
func (list *SqList) ListInsert(pos int, elem Node) error {
	//list是否已填满元素
	if list.length == MAXSIZE {
		err := errors.New("list space is full")
		return err
	}

	if pos < 1 || pos > list.length+1 {
		err := errors.New("invalid position")
		return err
	}

	if pos <= list.length {
		//将要插入位置之后的数据元素向后移动一位
		for i := list.length - 1; i >= (pos - 1); i-- {
			list.data[i+1] = list.data[i]
		}
	}

	list.data[pos-1] = elem
	list.length++

	return nil
}

/**
 * 删除L的第pos个数据元素，注意pos是指位置，第1个位置的数组是从0开始
 */
func (list *SqList) ListDelete(pos int) (Node, error) {
	if list.length == 0 {
		err := errors.New("empty list")
		return nil, err
	}

	if pos < 1 || pos > list.length {
		err := errors.New("invalid position")
		return nil, err
	}

	elem := list.data[pos-1]

	if pos < list.length {
		for i := pos; i < list.length; i++ {
			list.data[i-1] = list.data[i]
		}
	}
	list.length--

	return elem, nil
}

/**
 * 返回list中第pos个数据元素的值,注意pos是指位置，第1个位置的数组是从0开始
 */
func (list *SqList) GetElem(pos int) (Node, error) {
	if list.length == 0 {
		err := errors.New("empty list")
		return nil, err
	}

	if pos < 1 || pos > list.length {
		err := errors.New("invalid position")
		return nil, err
	}

	return list.data[pos-1], nil
}

/**
 * 打印list中的全部元素
 */
func (list *SqList) PrintElems() {
	for i := 0; i < list.length; i++ {
		fmt.Println("Key:", i, ",val:", list.data[i])
	}
}

/**
 * 判断线性表是否为空表
 */
func (list *SqList) ListEmpty() bool {
	return list.length == 0
}

/**
 * 清空list
 */
func (list *SqList) ClearList() {
	*list = SqList{}
}

func LocateElem(list *SqList, node Node) (int, error) {
	for i := 0; i < list.length; i++ {
		if node == list.data[i] {
			return i, nil
		}
	}

	return -1, errors.New("not found")
}
